import { defineStore } from 'pinia'
import { map } from 'lodash-es'
import type { DictResp } from '@/model/sys/dictModel'
import { getCache, removeCache, setCache } from '@/utils/cache'
import { DICT_KEY } from '@/enums/cacheEnum'
import type { Recordable } from '@/utils/types'
import { dictApi } from '@/api/sys/dictApi'
import { store } from '@/store'

interface DictState {
  dictValuesMap: DictCodeMap
  hasSet: boolean
  updatedAt: Date
}

interface DictCodeMap extends Recordable<Recordable<DictResp>> {
  [DICT_TYPE_CODE: string]: Recordable<DictResp>
}

export const useDictStore = defineStore('app-dict', {
  state: (): DictState => ({
    dictValuesMap: {},
    hasSet: false,
    updatedAt: new Date(1000),
  }),
  getters: {
    getDictCodeMap(state): DictCodeMap {
      return state.dictValuesMap ?? getCache<DictState>(DICT_KEY) ?? {}
    },
  },
  actions: {
    async setDictCodeMap() {
      if (!this.hasSet) {
        const { dictValuesMap } = await dictApi.valuesMap()
        this.dictValuesMap = dictValuesMap
        setCache(DICT_KEY, dictValuesMap)
        this.hasSet = true
      }
    },
    resetDictCodeMap() {
      this.dictValuesMap = {}
      this.hasSet = false
      removeCache(DICT_KEY)
    },
    getDictValues(dictTypeCode: string): Recordable<DictResp> {
      if (!dictTypeCode) {
        return {}
      }
      return this.dictValuesMap[dictTypeCode] ?? {}
    },
    getDictOptions(dictTypeCode: string): Recordable {
      const valueMapByDictCode = this.getDictValues(dictTypeCode)

      function transformValue(dictResp: DictResp) {
        const {
          dictMeta,
          dictValue,
        } = dictResp
        const valueType = dictMeta?.valueType ?? ''
        if (!valueType || !dictValue) {
          return dictValue
        }
        if (valueType === 'Boolean') {
          return dictValue === 'true'
        }
        if (valueType === 'Number') {
          return +dictValue
        }
        return dictValue
      }

      return map(valueMapByDictCode, dict => ({
        label: dict.dictName,
        value: transformValue(dict),
      }))
    },
    getDict(dictTypeCode: string, dictValue: string): DictResp {
      const dictValuesByDictTypeCode = this.getDictValues(dictTypeCode)
      if (!dictValue) {
        return {}
      }
      return dictValuesByDictTypeCode[dictValue] ?? {}
    },
    getDictName(dictTypeCode: string, dictValue: string): string {
      const dictValuesByDictTypeCode = this.getDictValues(dictTypeCode)
      if (!dictValue) {
        return ''
      }
      return dictValuesByDictTypeCode[dictValue]?.dictName ?? ''
    },
  },
})

export function useDictStoreWithout() {
  return useDictStore(store)
}
